﻿using Autofac;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Willow.IRepository;

namespace Willow.EFRepository
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly IComponentContext _componentContext;
        private Hashtable _repositories;
        protected readonly DbContext Context;


        public UnitOfWork(DbContext context, IComponentContext componentContext)
        {
            Context = context;
            _componentContext = componentContext;
        }

        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <param name="procedureCommand">The procedure command.</param>
        /// <param name="sqlParams">The SQL parameters.</param>
        public void ExecuteProcedure(string procedureCommand, params object[] sqlParams)
        {
            Context.Database.ExecuteSqlCommand(procedureCommand, sqlParams);
        }

        /// <summary>
        /// 保存更改
        /// </summary>
        public void SaveChanges()
        {
            Context.SaveChanges();
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (Context != null)
            {
                if (Context.GetValidationErrors().Count() == 0 && Context.ChangeTracker.HasChanges())
                {
                    //没有异常，提交更改
                    Context.SaveChanges();
                }
                Context.Dispose();
            }
        }

        /// <summary>
        /// 从IOC容器中获取数据操作对象
        /// </summary>
        /// <typeparam name="TRepository">The type of the repository.</typeparam>
        /// <returns></returns>
        public TRepository GetRepositoryFromIOC<TRepository>() where TRepository : class
        {
            return _componentContext.Resolve<TRepository>();
        }


        /// <summary>
        /// 获取泛型数据操作对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <returns></returns>
        public IRepository<TEntity> GetStandardRepository<TEntity>() where TEntity : class
        {
            if (_repositories == null)
            {
                _repositories = new Hashtable();
            }

            var type = typeof(TEntity).Name;

            if (_repositories.ContainsKey(type))
            {
                return (IRepository<TEntity>)_repositories[type];
            }

            var repositoryType = typeof(BaseRepository<>);
            _repositories.Add(type, Activator.CreateInstance(repositoryType.MakeGenericType(typeof(TEntity)), Context));

            return (IRepository<TEntity>)_repositories[type];
        }
    }
}
